package suery.syntax;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.LayoutManager;
import java.util.Queue;
import java.util.Set;

import suery.ComponentTreeNode;
import suery.SueryException;

/**
 * '[' and ']' in expression means to indicate the index of the component in a
 * list.</br> If there is an integer there, the parser will get the component
 * on the location which index indicated.</br> If there is a string ,the parser
 * will use the string as the constraints of the component in BorderLayout.
 * 
 * @author Jeky
 * @see java.awt.BorderLayout
 */
public class IndexParser implements TokenParser {

    @Override
    public void parse(Queue<String> tokenQueue,
            Set<ComponentTreeNode> parents,
            Set<ComponentTreeNode> results) {
        String index = tokenQueue.poll();

        try {
            // index of list
            int i = Integer.parseInt(index);
            ComponentTreeNode[] nodeArray =
                    parents.toArray(new ComponentTreeNode[0]);
            if (nodeArray.length <= i) {
                throw new SueryException.Parse(
                        "Index : " + index + "is out of range.");
            }
            results.add(nodeArray[i]);

        } catch (NumberFormatException e) {
            // BorderLayout Index
            String bIndex = Character.toUpperCase(index.charAt(0))
                    + index.substring(1).toLowerCase();
            for (ComponentTreeNode p : parents) {
                // get the layout manager of parent container
                Container container = p.getComponent().getParent();
                LayoutManager layout = container.getLayout();
                if (layout instanceof BorderLayout) {
                    // get the component the index indicated.
                    BorderLayout bLayout = (BorderLayout) layout;
                    Component component = bLayout.getLayoutComponent(bIndex);
                    if (component != null) {
                        new SearchByRefParser(component)
                                .parse(tokenQueue, parents, results);
                        return;
                    }
                }
            }
        }
    }

}
